#
# OpenCogAtomTypes.cmake
#
# Provide commands to generate bindings for AtomTypes in various
# languages (C++, scheme, python, OCaml, ...)
#
# -----------------
# Multiple macros are provided. These are:
#
# Generate C++ headers and files.
# OPENCOG_GEN_CXX_ATOMTYPES(
#        SCRIPT_FILE
#        CXX_HEADER_FILE
#        CXX_DEFINITIONS_FILE
#        CXX_INHERITANCE_FILE)
#
# Generate Scheme bindings:
# OPENCOG_GEN_SCM_ATOMTYPES(SCRIPT_FILE SCM_FILE)
# For example:
# OPENCOG_GEN_SCM_ATOMTYPES(atom_types.script atom_types.scm)
#
# Generate Python bindings:
# OPENCOG_GEN_PYTHON_ATOMTYPES(SCRIPT_FILE PYTHON_FILE)
#
# Generate OCaml bindings:
# OPENCOG_GEN_OCAML_ATOMTYPES(SCRIPT_FILE OCAML_FILE)
#
# Generate Atom Types bindings for three languages at once:
# C++, scheme and python. This is deprecated; it's best to
# use the above to make individual calls for each language.
#
# Macro example call:
# OPENCOG_ADD_ATOM_TYPES(
#        SCRIPT_FILE
#        CXX_HEADER_FILE
#        CXX_DEFINITIONS_FILE
#        CXX_INHERITANCE_FILE
#        SCM_FILE
#        PYTHON_FILE)
#
# -----------------
# Design notes.
#
# The CMake macros all run at the time the user says 'cmake ..'
# whereas the generation of Atom type bindings needs to happen at
# copile time, when the user says 'make'.  To do this, we use the
# ADD_CUSTOM_COMMAND that will run at compile time. However, as it
# happens, the scripts that generate the files are written in CMake
# itself, so this may be a source of confusion. That is, the below
# causes CMakefile to run at compile time, not cmake time. It might
# have been less confusing if the types were generated by perl scripts,
# instead of CMake. (And, actually, it would have been easier if they
# had been generated by perl scripts, but oh well...)
#
# Note:
# We need to set the working diretory because that is where the atom
# types script file is. However, doing so causes the values of
# CMAKE_BINARY_DIR, CMAKE_SOURCE_DIR, CMAKE_CURRENT_BINARY_DIR and
# CMAKE_CURRENT_SOURCE_DIR of the called macro in OpenCogGenWrapper.cmake
# to be the CMAKE_CURRENT_BINARY_DIR.
# -----------------

IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/OpenCogGenWrapper.cmake)
	SET(OC_CMAKE_PATH ${CMAKE_SOURCE_DIR})
ELSE()
	SET(OC_CMAKE_PATH ${ATOMSPACE_DATA_DIR})
ENDIF()
SET(OC_ATOM_TYPES_PATH ${OC_CMAKE_PATH}/cmake/OpenCogGenWrapper.cmake)

# =========================================================
# Generate C++ headers and files.
#
MACRO(OPENCOG_GEN_CXX_ATOMTYPES SCRIPT_FILE
      HEADER_FILE DEFINITIONS_FILE INHERITANCE_FILE)

	ADD_CUSTOM_COMMAND (
		COMMAND "${CMAKE_COMMAND}"
			-DBUILD_CXX="yes"
			-DOC_CMAKE_PATH=\"${OC_CMAKE_PATH}\"
			-DSCRIPT_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_FILE}\"
			-DHEADER_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${HEADER_FILE}\"
			-DDEFINITIONS_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${DEFINITIONS_FILE}\"
			-DINHERITANCE_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${INHERITANCE_FILE}\"
			-P "${OC_ATOM_TYPES_PATH}"
		OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${HEADER_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${DEFINITIONS_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${INHERITANCE_FILE}"
		DEPENDS "${SCRIPT_FILE}" "${OC_ATOM_TYPES_PATH}"
		WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
		COMMENT "Generating C++ Atom Type bindings from ${SCRIPT_FILE}"
	)
ENDMACRO()

# =========================================================
# Generate Scheme bindings.
#
MACRO(OPENCOG_GEN_SCM_ATOMTYPES SCRIPT_FILE SCM_FILE)

	ADD_CUSTOM_COMMAND (
		COMMAND "${CMAKE_COMMAND}"
			-DBUILD_SCM="yes"
			-DOC_CMAKE_PATH=\"${OC_CMAKE_PATH}\"
			-DSCRIPT_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_FILE}\"
			-DSCM_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${SCM_FILE}\"
			-P "${OC_ATOM_TYPES_PATH}"
		OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${SCM_FILE}"
		DEPENDS "${SCRIPT_FILE}" "${OC_ATOM_TYPES_PATH}"
		WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
		COMMENT "Generating Scheme Atom Type bindings from ${SCRIPT_FILE}"
	)
ENDMACRO()

# =========================================================
# Generate Python bindings.
#
MACRO(OPENCOG_GEN_PYTHON_ATOMTYPES SCRIPT_FILE PYTHON_FILE)

	ADD_CUSTOM_COMMAND (
		COMMAND "${CMAKE_COMMAND}"
			-DBUILD_PYTHON="yes"
			-DOC_CMAKE_PATH=\"${OC_CMAKE_PATH}\"
			-DSCRIPT_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_FILE}\"
			-DPYTHON_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_FILE}\"
			-P "${OC_ATOM_TYPES_PATH}"
		OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_FILE}"
		DEPENDS "${SCRIPT_FILE}" "${OC_ATOM_TYPES_PATH}"
		WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
		COMMENT "Generating Python Atom Type bindings from ${SCRIPT_FILE}"
	)
ENDMACRO()

# =========================================================
# Generate OCaml bindings.
#
MACRO(OPENCOG_GEN_OCAML_ATOMTYPES SCRIPT_FILE OCAML_FILE WRAPPER_FILE HEADER_FILE)

	ADD_CUSTOM_COMMAND (
		COMMAND ${CMAKE_COMMAND}
			-DBUILD_OCAML="yes"
			-DOC_CMAKE_PATH=\"${OC_CMAKE_PATH}\"
			-DSCRIPT_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_FILE}\"
			-DOCAML_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${OCAML_FILE}\"
			-DWRAPPER_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${WRAPPER_FILE}\"
			-DHEADER_FILE=\"${HEADER_FILE}\"
			-P ${OC_ATOM_TYPES_PATH}
		OUTPUT  ${OCAML_FILE} ${WRAPPER_FILE}
		DEPENDS ${SCRIPT_FILE} ${OC_ATOM_TYPES_PATH}
		WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
		COMMENT "Generating OCaml Atom Type bindings from ${SCRIPT_FILE}"
	)

ENDMACRO()

# =========================================================
# Deprecated, do not use in new code.
#

MACRO(OPENCOG_ADD_ATOM_TYPES SCRIPT_FILE
      HEADER_FILE DEFINITIONS_FILE INHERITANCE_FILE SCM_FILE PYTHON_FILE)

# We want to be able to say just this:
#
#	OPENCOG_GEN_SCM_ATOMTYPES(${SCRIPT_FILE} ${SCM_FILE})
#	OPENCOG_GEN_PYTHON_ATOMTYPES(${SCRIPT_FILE} ${PYTHON_FILE})
#	OPENCOG_GEN_CXX_ATOMTYPES(${SCRIPT_FILE}
#		${HEADER_FILE} ${DEFINITIONS_FILE} ${INHERITANCE_FILE})
#
# but we can't, because missing dependencies in assorted projects
# would cause the scheme and python files to not be generated.
# No amount of ADD_CUSTOM_TARGET here seeems able to fix this,
# So we do the below instead.

	ADD_CUSTOM_COMMAND (
		COMMAND "${CMAKE_COMMAND}"
			-DBUILD_CSP=yes
			-DOC_CMAKE_PATH=\"${OC_CMAKE_PATH}\"
			-DSCRIPT_FILE=\"${CMAKE_CURRENT_SOURCE_DIR}/${SCRIPT_FILE}\"
			-DHEADER_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${HEADER_FILE}\"
			-DDEFINITIONS_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${DEFINITIONS_FILE}\"
			-DINHERITANCE_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${INHERITANCE_FILE}\"
			-DSCM_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${SCM_FILE}\"
			-DPYTHON_FILE=\"${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_FILE}\"
			-P "${OC_ATOM_TYPES_PATH}"
		OUTPUT  "${CMAKE_CURRENT_BINARY_DIR}/${HEADER_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${DEFINITIONS_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${INHERITANCE_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${SCM_FILE}"
		        "${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_FILE}"
		DEPENDS "${SCRIPT_FILE}" "${OC_ATOM_TYPES_PATH}"
		WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
		COMMENT "Generating C++, Scheme, Python Atom Type bindings from ${SCRIPT_FILE}"
	)
ENDMACRO()

# =========================================================
